iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0

實作

先建表, CHANNEL_MAP 的索引表示通道 id,這邊暫時用數值 id,因此以陣列方式實現。若為字串 id 則用 Map 表現。

private readonly CHANNEL_MAP = [
  [61, 24],
  [64, 47],
  [63, 4],
  [17, 62],
  [11, 56],
  [43, 23],
  [16, 48],
  [57, 20],
  [20, 10],
  [20, 34],
  [34, 10],
  [57, 10],
  [57, 34],
  [26, 44],
  [7, 31],
  [1, 8],
  [13, 33],
  [15, 5],
  [2, 14],
  [46, 29],
  [25, 51],
  [21, 45],
  [37, 40],
  [12, 22],
  [35, 36],
  [27, 50],
  [32, 54],
  [28, 38],
  [18, 58],
  [42, 53],
  [3, 60],
  [9, 52],
  [59, 6],
  [19, 49],
  [39, 55],
  [41, 30],
];

接著建立反向表,用於查詢某閘門屬於哪個通道。

private readonly REVERSE_CHANNEL_MAP = new Map<number, number>(
  this.CHANNEL_MAP.flatMap(([g1, g2], idx) => [
    [g1, idx] as const,
    [g2, idx] as const,
  ]),
);

最後實作演算法:

public getChannels(gates: number[]): number[] {
  const channels = [];
  const candidate = new Set();

  for (const gate of gates) {
    const channel = this.REVERSE_CHANNEL_MAP.get(gate);
    assert(channel);

    if (candidate.has(channel)) {
      candidate.delete(channel);
      channels.push(channel);
    } else {
      candidate.add(channel);
    }
  }

  return channels;
}

編寫測試

it('getChannels()', () => {
  expect(
    service.getChannels([
      48, 21, 5, 30, 29, 6, 14, 39, 58, 10, 38, 1, 13, 7, 61, 41, 9, 52, 54,
    ]),
  ).toEqual([35, 31]);
});

得到結果:

> jest

 PASS  src/body-graph/body-graph.service.spec.ts
  BodyGraphService
    ✓ getDesignDate() (6 ms)
    ✓ getDesignDate() (3 ms)
    ✓ getBodyGraph() (3 ms)
    ✓ getChannels() (1 ms)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        1.182 s, estimated 2 s
Ran all test suites.

晚安,瑪卡巴卡。


上一篇
看懂自己的說明書 1:閘門與通道
下一篇
看懂自己的說明書 3:人類圖解析
系列文
「莫忘初衷,從猴子到超人」:一個獻給自由精靈的社群媒合引擎18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言